package com.smh;

import org.junit.jupiter.api.Test;

import java.util.Iterator;

/**
 * @author shiminghui
 * @date 2025/2/17 17:46
 * @description: TODO
 */
public class _022_双端队列_数组 {
    @Test
    public void test01() {
        MyDeque<Integer> deque = new MyDeque<>(3);
        deque.offerFirst(1);
        deque.offerLast(2);
        deque.offerFirst(3);
        for (Integer i : deque) {
            System.out.println(i);
        }
    }

    private class MyDeque<T> implements Iterable<T> {
        private T[] data;
        private int head; // 指向队首,
        private int tail; // 指向队尾,并且最终尾部的位置没有数据
        private int size;
        private int capacity;

        @SuppressWarnings("unchecked") // 消除警告
        public MyDeque(int capacity) {
            this.capacity = capacity + 1;
            data = (T[]) new Object[capacity + 1];
            head = 0;
            tail = 0;
            size = 0;
        }

        public MyDeque() {
            this(10);
        }

        public boolean offerFirst(T data) {
            if (isFull()) {
                return false;
            }
            head = (head - 1 + capacity) % capacity;
            this.data[head] = data;
            size++;
            return true;
        }

        public boolean offerLast(T data) {
            if (isFull()) {
                return false;
            }
            this.data[tail] = data;
            tail = (tail + 1) % capacity;
            size++;
            return true;
        }

        public T pollFirst() {
            if (isEmpty()) {
                return null;
            }
            T value = data[head];
            data[head] = null; // help GC
            head = (head + 1) % capacity;
            size--;
            return value;
        }

        public T pollLast() {
            if (isEmpty()) {
                return null;
            }
            tail = (tail - 1 + capacity) % capacity;
            T value = data[tail];
            data[tail] = null; // help GC
            size--;
            return value;
        }

        public T peekFirst() {
            if (isEmpty()) {
                return null;
            }
            return data[head];
        }

        public T peekLast() {
            if (isEmpty()) {
                return null;
            }
            return data[(tail - 1 + capacity) % capacity];
        }

        public boolean isEmpty() {
            return size == 0;
        }

        public boolean isFull() {
            return size == capacity - 1;
        }


        @Override
        public Iterator<T> iterator() {
            return new Iterator<T>() {
                private int index = head;

                @Override
                public boolean hasNext() {
                    if (index != tail) {
                        return true;
                    }
                    return false;
                }

                @Override
                public T next() {
                    T value = data[index];
                    index = (index + 1) % capacity;
                    return value;
                }
            };
        }
    }

}
